<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title> 泛型 </title>
</head>
<body>
</body>
</html>
<script>
    //2021-02-16-17-30
    /*在你远处的都是风景 在你眼前的才是人生*/
    //2021-05-18-白     
    //2021-06-03-夜-修订补充
    //2021-08-04-夜-修订

    //泛型Generics：在定义函数，接口或者类时，不预先指定具体的类型，而是在使用时在指定类型的一种特性   
    //用于提升代码的重用性,编写模块组件业务逻辑时

//ts函数 泛型难点 
    //在工作中，我们经常使用<T>来作泛型的表示，当然这不是硬性的规定，只是大部分程序员的习惯性写法。demo代码如下

    /*编写一个简单的join方法函数，
      方法接受两个参数first和second,参数有可能是字符串类型，也有可能是数字类型。
      方法里为了保证都可以使用，所以我们只作了字符串的基本拼接*/
    function join(first:string|number, second:string|number){
        return `${first}${second}`;
    }
    join("常","东东"); 
    //添加需求 
    //即如果   first参数传的时字符串类型 要求second也传字符串类型 
    //同理     如果是number类型 就都是number类型 同时抛出

//即需要泛型来解决这问题 ?
//初始泛型概念 generic
    //generic通用,泛指的意思 简单理解泛型就是泛指的类型 
    //泛型的定义使用<>(尖角号)  
    //比如现在给jion方法一个泛型 名字叫cdd(名字随便 规范符合语义化即可)
    //后面参数 这时候也使用 刚定义的泛型名称 然后调用这个方法时 就需要具体指明泛型的类型了 
    function join<cdd>(first:cdd,second:cdd){
        return `${first}${second}`;
    }
    join<string>("常","东东");
    //如果是number类型 就直接在调用方法时 进行更改即可 
    join<number>(1,2);
    //对泛型理解在实际开发中 
    //!!注意    有很多对象和类的情况里边的具体类型我们没办法了解   所以提供了这种泛型的概念        


//泛型中数组的使用 
    //如果传递过来的值 要求是数字用泛型定义 两种方式 
    //1 直接使用[]  
    //2 使用Array<泛型> 形式不一样其它都一样 
    //方法一 
    function myFun<ANY>(params:ANY[]){
        return params;
    }
    myFun<string>["我","尼玛"];
    //方法二 
    function myFun<ANY>(params: Array[ANY]){  
        return params;
    }        
    myFun<string>["我","尼玛"]  


//多个泛型的定义  
    //一个函数可以定义多个泛型 demo代码如下  定义多个泛型 比如第一个T 第二个P代表 
    function join<T,P>(first:T,second:P){
        return   `${first}${second}`
    }
    join<number,string>(1,"2");
    //会了两种 三种也一样 泛型经常使用 灵活性 
    //注意 如果函数定义了多个泛型 使用时 要对应的定义出具体的类型  
 

//泛型的类型推断  
    //泛型也时支持类型推断的 比如下面的代码 就是类型推断的功劳 
    function join<T,P>(first:T,second:P){
        return `${first}${second}`
    }
    join(1,"2")
    //建议不要大量使用类型推论 这样会使你的代码易读性 健壮性下降 










































//ts 中的泛型  
        //定义函数 接口 类的时候 不预先指定具体类型 而是在使用的时候再指定类型的一种特性 维护性更高 
        //泛型用来帮助我们限定约束规范 
        //dmeo中没有确切定义返回值类型 运行的数组每一项都可以时任意类型  
        function createArray(length:number,value:any):Array<any>{
                let arr = []
                for(var i=0; i<length; i++){
                        arr[i] = value
                }
                return arr;
        }        
        createArray(3,1) 
        //使用泛型修改上面的代码  
        function createArray<T>(length:number,value:T):Array<T>{
                let arr = []
                for(var i=0; i<length; i++){
                        arr[i] = value
                }
                return arr;
        }        
        var strArry:string[] = createArray<string>(3,"1")   //规定返回值value为字符串  
        var numArray:number[] = createArray(3,1)            //不传时 进行反推值  
        //接口当中采用泛型  
        interface Icreate{
                <T>(name:string,value:T):Array<T>
        }
        let func:Icreate;
        func = function<T>(name:string,value:T):Array<T>{
                return []
        }
        var strArr:string[] = func("ahncsan","str")

</script>